import 'dart:core';

import 'package:flutter/material.dart';
import 'package:stage_manager/parts/journalItemDialog.dart';

import '../common/flatPanel.dart';
import '../models/journalItem.dart';
import '../utils/dataSource.dart';
import '../utils/screw.dart';

mixin DailyController {
  final mDb = DataSource();

  String mTable;
  var mViewState = ViewState.Initial;

  String mMonth;
  String mDate;
  var mMonths = <String>[];
  var mDates = <String>[];
  var mItems = <JournalItem>[];
  var placeHolder = -1;
  JournalItem mItem;

  void onTapItem();

  void onAddItem();

  void onEditItem();

  void onUpdateView();

  void disposeAction() {
    mMonths.clear();
    mDates.clear();
    mItems.clear();
    mDb.close();
  }

  Future<void> connectDbAction(BuildContext context, String configName, Function function) async
  {
    bool result = await mDb.connectFromHive(configName);
    if (result) {
      function();
    } else {
      Screw.showToast(context, '无法连接到数据库!');
    }
  }

  Future<void> addItemAction(BuildContext context) async {
    var item = await showJournalItemDialog(context, item: JournalItem());
    if (mDb.isConnect) {
      var result = await mDb.query(
          'insert into $mTable (month_,date_,category,detail) values (?,?,?,?)',
          [item.month, item.date, item.category, item.detail]);
      if (result.affectedRows == 1) onUpdateView();
    }
  }

  Future<void> editItemAction(BuildContext context) async {
    if (mItem == null || mItem.id == 0) return;

    var item = await showJournalItemDialog(context, item: mItem);
    if (mItem.isEqual(item)) return;

    if (mDb.isConnect) {
      var result = await mDb.query('update $mTable set category=?,detail=?',
          [mItem.category, mItem.detail]);
      if (result.affectedRows == 1) onUpdateView();
    }
  }

  Future<void> updateMonthsAction() async {
    if (mMonths.isNotEmpty) mMonths.clear();
    if (mDb.isConnect) {
      var items = <String>[];
      var results = await mDb.query(
          'select month_ from $mTable group by month_ ORDER BY month_ DESC');
      results.forEach((element) {
        items.add(element[0]);
      });
      mMonths = items;
    }
    if (mMonths.isEmpty) mMonths.add(Screw.genMonthString());
  }

  Future<void> updateDatesAction() async {
    if (mMonth.isEmpty) return;
    if (mDates.isNotEmpty) mDates.clear();
    if (mDb.isConnect) {
      var items = <String>[];
      var results = await mDb.query(
          'select date_ from $mTable where month_=? group by date_ ORDER BY date_ DESC',
          [mMonth]);
      results.forEach((element) {
        items.add(element[0]);
      });
      mDates = items;
    }
  }

  Future<void> updateViewAction() async {
    if (mDate.isEmpty) return;

    if (mDb.isConnect) {
      var items = <JournalItem>[];
      var results = await mDb.query(
          'select id,month_,date_,category,detail from $mTable where date_=?',
          [mDate]);
      results.forEach((element) {
        var item = JournalItem(
          id: element[0],
          month: element[1],
          date: element[2],
          category: element[3],
          detail: element[4].toString(),
        );
        items.add(item);
      });
      mItems = items;
    }
  }

  Widget genDatesViewAction() {
    return ListView.builder(
      itemCount: mDates.length,
      itemBuilder: (c, index) {
        return ListTile(
          leading: Icon(Icons.arrow_forward_ios),
          title: Text(
            mDates[index],
          ),
          onTap: () {
            mDate = mDates[index];
            onUpdateView();
          },
        );
      },
    );
  }

  Widget genDetailViewAction() {
    return ListView.separated(
      itemCount: mItems.length,
      itemBuilder: (c, index) {
        return ListTile(
          leading: Icon(placeHolder == mItems[index].id
              ? Icons.radio_button_on
              : Icons.radio_button_off),
          title: Text(mItems[index].detail, style: getTextStyle()),
          onTap: () {
            mItem = mItems[index];
            onTapItem();
          },
        );
      },
      separatorBuilder: (c, index) => Divider(),
    );
  }
}
